﻿//++
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//  ConferenceInfo.cs
//    
// Abstract:
//
//  This module implements helper class to extract Conference information from appointment item
//  
//--

using System;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace Microsoft.EnhancedReminders.OutlookAddIn
{
    /// <summary>
    /// Helper class to extract Conference information from appointment item.
    /// </summary>
    public class ConferenceInfo
    {
        private static Regex _uriRegex =
            new Regex(@"HYPERLINK\s+""(?<type>(conf|meet)):(?<uri>sip:[^""]+)""",
            RegexOptions.Compiled | RegexOptions.IgnoreCase);

        private readonly string _conferenceAddress;
        private readonly ConferenceType _conferenceType = ConferenceType.None;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="appointmentBody">The body of an Outlook Appointment.</param>
        public ConferenceInfo(string appointmentBody)
        {
            if (String.IsNullOrEmpty(appointmentBody))
            {
                return;
            }

            Match match = _uriRegex.Match(appointmentBody);
            if (!match.Success)
            {
                return;
            }

            _conferenceAddress = match.Groups["uri"].Value;
            Debug.Assert(_conferenceAddress != null, "_meetingUri != null");

            // Remove URI escapes and clip off the "conversation-id" tag in the case 
            // of a conference call URI.
            _conferenceAddress = Uri.UnescapeDataString(_conferenceAddress);

            int index = _conferenceAddress.LastIndexOf("?conversation-id", StringComparison.OrdinalIgnoreCase);
            if (index > 0)
            {
                _conferenceAddress = _conferenceAddress.Remove(index);
            }

            _conferenceType = match.Groups["type"].Value.Equals("meet", StringComparison.OrdinalIgnoreCase)? ConferenceType.LiveMeeting : ConferenceType.ConferenceCall;

            Debug.Assert(_conferenceType == ConferenceType.ConferenceCall || match.Groups["type"].Value.Equals("meet", StringComparison.OrdinalIgnoreCase), "Conference is either Live Meeting or Conference Call");
        }

        /// <summary>
        /// Indicate if the appointment is a conference call/live meeting
        /// </summary>
        public ConferenceType ConferenceType
        {
            get
            {
                return _conferenceType;
            }
        }

        /// <summary>
        /// Meeting URL
        /// </summary>
        public string ConferenceAddress
        {
            get
            {
                return _conferenceAddress;
            }
        }

        /// <summary>
        /// Strips out the id portion of a meeting uri.
        /// 
        /// Example conference call URI: 
        /// conf:sip:username@domain;gruu;opaque=app:conf:focus:id:09fb6203f667472fa5e38c19f92719c3%3Fconversation-id=798051c8e5614a1fb7079da0bc8e2004
        /// 
        /// Example live meeting URI: 
        /// meet:sip:username@domain;gruu;opaque=app:conf:focus:id:c2aeefaf7bd7410e997e955e82126712
        /// </summary>
        public string MeetingId
        {
            get
            {
                if (null == _conferenceAddress)
                {
                    return null;
                }

                int index = _conferenceAddress.LastIndexOf("id:", StringComparison.OrdinalIgnoreCase);

                string id = _conferenceAddress.Substring(index + 3);

                Debug.Assert(id.Length >= 8 && id.Length <= 32, "Expecting alpha-numeric id of length 8-32 characters.");

                return id;
            }
        }
    }
}